
#include <bur/plctypes.h>

#include <string.h>
#ifdef _DEFAULT_INCLUDES
#include <AsDefault.h>
#endif


void _INIT ProgramInit(void)
{
	VCHandle = VA_Setup(1, (STRING*)VISU_NAME);
	RTInfo_0.enable = 1;
	RTInfo(&RTInfo_0);
}

void _CYCLIC ProgramCyclic(void)
{
	int i, j;
	//Read all the axis error
	for(i = 0; i <= AXIS_MAX_INDEX; i++)
	{
		if(gAlarmCtrl.Required[i] == 1)
		{
			if(gAlarmCtrl.Acknowledge[i] == 0)
			{
				//reset the request, and start to wait 1 second.
				gAxisCtrl[i].Command.ErrorAcknowledge = 1;
				gAlarmCtrl.Reqest[i] = 0;
				gAlarmCtrl.Required[i] = 0;
				AxisWaitReset[i] = 1;
				AxisWaitTime[i] = 0;
			}
			continue;
		}
		else
		{
			if(AxisWaitReset[i] == 1)
			{
				AxisWaitTime[i] += RTInfo_0.cycle_time;
				if(AxisWaitTime[i] > 1000000)
				{
					AxisWaitReset[i] = 0;
					AxisWaitTime[i] = 0;
				}
				continue;
			}
		}
		if(gAxisCtrl[i].Error.AxisErrorCount != 0)
		{
			if(gAxisCtrl[i].Error.ErrorID != 0)
			{
				gAlarmCtrl.AxisErrorID[i] = gAxisCtrl[i].Error.ErrorID;
				gAlarmCtrl.Reqest[i] = 1;
			}
			else
			{
				//do nothing to wait the ErrorID valid
			}
		}
		else
		{
			gAlarmCtrl.AxisErrorID[i] = 0;
			if(gAxisCtrl[i].AxisState.ErrorStop == 1)
			{
				gAlarmCtrl.Reqest[i] = 1;
			}
			else
			{
				gAlarmCtrl.Reqest[i] = 0;
			}
		}
	}
	//reset all the action
	memset(&tmpAction, 0, sizeof(tmpAction));

	if(gAlarmCtrl.Command.AckAll == 1 && tmpAckAll == 0)
	{
		//set the ack rising edge
		tmpAckAllR = 1;
	}
	else
	{
		tmpAckAllR = 0;
	}
	if(gAlarmCtrl.Command.Mute == 1 && tmpMute == 0)
	{
		gAlarmCtrl.Command.Mute = 0;
		//set the mute rising edge
		tmpMuteR = 1;
	}
	else
	{
		tmpMuteR = 0;
	}
	tmpAckAll = gAlarmCtrl.Command.AckAll;

	//check all the alarms, and set the action as configured
	gAlarmCtrl.Status.ActiveNumber = 0;
	gAlarmCtrl.Status.AcknowledgedNumber = 0;
	for(i = 0; i < ALARM_NUMBER; i++)
	{
		if (gAlarmCtrl.Reqest[i] == 1)
		{
			//set the required to 1, to handle the alarm
			if(gAlarmCtrl.Required[i] == 0)
			{
				gAlarmCtrl.Required[i] = 1;
			}
			gAlarmCtrl.Acknowledge[i] = 1;
		}
		else
		{
			if(gAlarmCtrl.Required[i] == 1)
			{
				//Alarm has been reseted, check whether it should be hold until Acknowledge
				if(gAlarmCtrl.Config[i].Hold == 0)
				{
					gAlarmCtrl.Required[i] = 0;
				}
				else
				{
					//hold
					gAlarmCtrl.Required[i] = gAlarmCtrl.Acknowledge[i];
				}
			}
		}

		if(tmpAckAllR == 1)
		{
			//in this block, the handling of ack is redundant to the
			//VA_QuitAlarms
			if(gAlarmCtrl.Required[i] == 1)
			{
				//alarm occured
				//set the ack bit, when AckAll rising edge
				if(gAlarmCtrl.Reqest[i] == 0)
				{
					//holding alarm, reset the required
					gAlarmCtrl.Required[i] = 0;
				}
				//				else
				//				{
				gAlarmCtrl.Acknowledge[i] = 0;
				//				}
			}
		}
		if (gAlarmCtrl.Config[i].Mask == 1)
		{
			continue;
		}
		if(gAlarmCtrl.Required[i] == 1)
		{
			//count the alarm
			gAlarmCtrl.Status.ActiveNumber += 1;
			if(gAlarmCtrl.Acknowledge[i] == 0)
			{
				gAlarmCtrl.Status.AcknowledgedNumber += 1;
			}
			if(tmpMuteR == 1)
			{
				gAlarmCtrl.Muted[i] = 1;
			}
			if((gAlarmCtrl.Acknowledge[i] == 1) || (gAlarmCtrl.Config[i].ValidAfterAck == 1))
			{
				//not Acknowledge or valid after Acknowledge, means this alarm is active
				//Set the action as configured
				tmpAction.EStop |= gAlarmCtrl.Config[i].EStop;
				tmpAction.SlowDown |= gAlarmCtrl.Config[i].SlowDown;
				tmpAction.Stop |= gAlarmCtrl.Config[i].Stop;
				tmpAction.Beep |= ((!gAlarmCtrl.Muted[i]) && (gAlarmCtrl.Config[i].Beep && ((gAlarmCtrl.Config[i].BeepAfterAck == 1) || (gAlarmCtrl.Acknowledge[i] == 1))));
				for(j = 0; j < ALARM_USER_ACTION_NUMBER; j++)
				{
					tmpAction.User[j] |= gAlarmCtrl.Config[i].UserAction[j];
				}
			}
			else
			{
				// do nothing
			}
		}
		else
		{
			//alarm not set, reset the Acknowledge and muted
			gAlarmCtrl.Acknowledge[i] = 0;
			gAlarmCtrl.Muted[i] = 0;
		}
	}

	if((tmpAckAllR == 1) || (ret == 247))
	{
		if (VCHandle)
		{
			ret = VA_Saccess(1, VCHandle);
			if(ret == 0)
			{
				ret = VA_QuitAlarms(1, VCHandle, 65535);
				VA_Srelease(1, VCHandle);
			}else
			{
				//access faild, set ret to 247 to reaccess this block
				ret = 247;
			}
		}
	}
	else
	{
		//handle the axis alarm text
		if(AxisTextTimer < 500000)
		{
			AxisTextTimer += RTInfo_0.cycle_time;
		}
		else
		{
			if (VCHandle)
			{
				ret = VA_Saccess(1, VCHandle);
				if(ret == 0)
				{
					ret = VA_NGetAlCurPos(1, VCHandle, (DINT)&GroupNo, (DINT)&CurrentAlarmNo);
					if(ret == 0)
					{
						if(CurrentAlarmNo <= AXIS_MAX_INDEX)
						{
							memcpy(gAlarmCtrl.AxisErrorText, gAxisCtrl[CurrentAlarmNo].Error.ErrorText, sizeof(gAlarmCtrl.AxisErrorText));
						}
						else
						{
							memset(gAlarmCtrl.AxisErrorText, 0, sizeof(gAlarmCtrl.AxisErrorText));
						}
						AxisTextTimer = 0;
					}
					else
					{
						memset(gAlarmCtrl.AxisErrorText, 0, sizeof(gAlarmCtrl.AxisErrorText));
					}
					VA_Srelease(1, VCHandle);
				}
			}
		}
	}
	gAlarmCtrl.Action = tmpAction;
	
}

void _EXIT ProgramExit(void)
{

}

